<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>作用域</title>
</head>
<body>

</body>
<script>
    /**
     * [[scope]]: 每个jsvascript函数都是一个对象,
     * 对象中有些属性我们可以访问,但有些不可以,
     * 这些属性仅供javascript引擎存取,[[scope]]就是其中一个
     * [[scope]]指的就是我们所说的作用域,其中存储了运行期上下文的集和
     *
     * 作用域链 : [[scope]]中所存储的执行期上下文对象的集和,这个集和呈链式链接,我们把这种链接叫做作用域链
     *
     * 执行期上下文 : 当函数执行时,会创建一个称为 执行期上下文 的内部对象.
     * 一个执行期上下文定义了一个函数执行时的环境,
     * 函数每次执行时对应的执行期上下文都是独一无二的,
     * 所以多次调用一个函数会导致创建多个执行期上下文,
     * 当函数执行完毕, 它所产生的执行期上下文被销毁
     *
     * 查找变量 : 从作用域链的顶端依次向下查找
     */
    function a() {

        function b() {
            var b = 234;
            aa = 0;
        }

        var aa = 123;
        b();
        console.log(aa);
    }

    var glob = 100;
    a();

    // a defined a.[[scope]]  --->  0 : GO {
    //                                      glob : undefined
    //                                      a : function() {}
    //                                  }
    // a doing   a.[[scope]]  --->  0 : AO {
    //                                      aa : undefined
    //                                      b : function() {}
    //                                  } a
    //                         --->  1 : GO {
    //                                       glob : undefined
    //                                       a : function() {}
    //                                   }
    //
    // b defined b.[[scope]]  --->  0 : AO {
    //                                      aa : undefined
    //                                      b : function() {}
    //                                  } a
    //                        --->  1 : GO {
    //                                      glob : undefined
    //                                      a : function() {}
    //                                  }
    // b doing     b.[[scope]]  --->  0 : AO {
    //                                        b : undefined
    //                                    } b
    //                          --->  1 : AO {
    //                                        aa : undefined
    //                                        b : function() {}
    //                                    } a
    //                          --->  2 : GO {
    //                                        glob : undefined
    //                                        a : function() {}
    //                                    }
</script>
</html>
